package com.xiaoniu.common.utils;

import com.google.common.eventbus.AsyncEventBus;
import com.xiaoniu.common.base.inter.Register;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Service;

import java.util.Collection;
import java.util.concurrent.*;

/**
 * @author zhangjianshan on 2021-05-11
 */
@Log4j2
@Service
public class EventBusUtil implements ApplicationContextAware {
    private EventBusUtil() {
    }

    public static volatile AsyncEventBus asyBus;

    private static Collection<Register> registerList;


    public static AsyncEventBus getInstance() {
        if (asyBus == null) {
            synchronized (EventBusUtil.class) {
                if (asyBus == null) {
                    //无界的任务队列
                    ExecutorService pool = new ThreadPoolExecutor(1, 2, 1000,
                            TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(),
                            Executors.defaultThreadFactory(),
                            new ThreadPoolExecutor.CallerRunsPolicy());
                    asyBus = new AsyncEventBus(String.valueOf(asyBus), pool);
                    loadRegister();
                }
            }
        }
        return asyBus;
    }

    public static void loadRegister() {
        registerList.forEach(EventBusUtil::register);
    }

    private static void register(Register register) {
        try {
            getInstance().register(register.getClass().newInstance());
        } catch (Exception e) {
            log.error(e.getMessage());
        }

    }


    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        registerList = applicationContext.getBeansOfType(Register.class).values();
    }
}
